﻿/****************************************************************************** 
* $Id$ 
* 
* Name:     GDALInfo.cs 
* Project:  GDAL CSharp Interface 
* Purpose:  A sample app to read GDAL raster data information. 
* Author:   Tamas Szekeres, szekerest@gmail.com 
* 
****************************************************************************** 
* Copyright (c) 2007, Tamas Szekeres 
* 
* Permission is hereby granted, free of charge, to any person obtaining a 
* copy of this software and associated documentation files (the "Software"), 
* to deal in the Software without restriction, including without limitation 
* the rights to use, copy, modify, merge, publish, distribute, sublicense, 
* and/or sell copies of the Software, and to permit persons to whom the 
* Software is furnished to do so, subject to the following conditions: 
* 
* The above copyright notice and this permission notice shall be included 
* in all copies or substantial portions of the Software. 
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
* DEALINGS IN THE SOFTWARE. 
*****************************************************************************/

using System;
using OSGeo.GDAL;
using OSGeo.OSR;

/**
 * Author: Surapong Lertrattanapanich
 * Description: This sample code is modified so that the target platform is changed
 * from console application to window application
 */


/// <summary> 
/// A C# based sample to read GDAL raster data information. 
/// </summary>  

namespace Okra.NstdaGisTool {
    class GDALInfo {
        public static string getGdalInfo(string strPath) {
            string strInfo = "\n";

            try {
                /* -------------------------------------------------------------------- */
                /*      Register driver(s).                                             */
                /* -------------------------------------------------------------------- */
                //Gdal.AllRegister(); 

                /* -------------------------------------------------------------------- */
                /*      Open dataset.                                                   */
                /* -------------------------------------------------------------------- */
                Dataset ds = Gdal.Open(strPath, Access.GA_ReadOnly);

                if (ds == null) {
                    strInfo += "\nCan't open " + strPath;
                }

                strInfo += "\nRaster dataset parameters:";
                strInfo += "\n  Projection: " + ds.GetProjectionRef();
                strInfo += "\n  RasterCount: " + ds.RasterCount;
                strInfo += "\n  RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")";

                /* -------------------------------------------------------------------- */
                /*      Get driver                                                      */
                /* -------------------------------------------------------------------- */
                Driver drv = ds.GetDriver();

                if (drv == null) {
                    strInfo += "\nCan't get driver.";
                    System.Environment.Exit(-1);
                }

                strInfo += "\nUsing driver " + drv.LongName;

                /* -------------------------------------------------------------------- */
                /*      Get metadata                                                    */
                /* -------------------------------------------------------------------- */
                string[] metadata = ds.GetMetadata("");
                if (metadata.Length > 0) {
                    strInfo += "\n  Metadata:";
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++) {
                        strInfo += "\n    " + iMeta + ":  " + metadata[iMeta];
                    }
                    strInfo += "\n";
                }

                /* -------------------------------------------------------------------- */
                /*      Report "IMAGE_STRUCTURE" metadata.                              */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("IMAGE_STRUCTURE");
                if (metadata.Length > 0) {
                    strInfo += "\n  Image Structure Metadata:";
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++) {
                        strInfo += "\n    " + iMeta + ":  " + metadata[iMeta];
                    }
                    strInfo += "\n";
                }

                /* -------------------------------------------------------------------- */
                /*      Report subdatasets.                                             */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("SUBDATASETS");
                if (metadata.Length > 0) {
                    strInfo += "\n  Subdatasets:";
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++) {
                        strInfo += "\n    " + iMeta + ":  " + metadata[iMeta];
                    }
                    strInfo += "\n";
                }

                /* -------------------------------------------------------------------- */
                /*      Report geolocation.                                             */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("GEOLOCATION");
                if (metadata.Length > 0) {
                    strInfo += "\n  Geolocation:";
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++) {
                        strInfo += "\n    " + iMeta + ":  " + metadata[iMeta];
                    }
                    strInfo += "\n";
                }

                /* -------------------------------------------------------------------- */
                /*      Report corners.                                                 */
                /* -------------------------------------------------------------------- */
                strInfo += "\nCorner Coordinates:";
                strInfo += "\n  Upper Left (" + GDALInfoGetPosition(ds, 0.0, 0.0) + ")";
                strInfo += "\n  Lower Left (" + GDALInfoGetPosition(ds, 0.0, ds.RasterYSize) + ")";
                strInfo += "\n  Upper Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, 0.0) + ")";
                strInfo += "\n  Lower Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, ds.RasterYSize) + ")";
                strInfo += "\n  Center (" + GDALInfoGetPosition(ds, ds.RasterXSize / 2, ds.RasterYSize / 2) + ")";
                strInfo += "\n";

                /* -------------------------------------------------------------------- */
                /*      Report projection.                                              */
                /* -------------------------------------------------------------------- */
                string projection = ds.GetProjectionRef();
                if (projection != null) {
                    SpatialReference srs = new SpatialReference(null);
                    if (srs.ImportFromWkt(ref projection) == 0) {
                        string wkt;
                        srs.ExportToPrettyWkt(out wkt, 0);
                        strInfo += "\nCoordinate System is:";
                        Console.WriteLine(wkt);
                    }
                    else {
                        strInfo += "\nCoordinate System is:";
                        Console.WriteLine(projection);
                    }
                }

                /* -------------------------------------------------------------------- */
                /*      Report GCPs.                                                    */
                /* -------------------------------------------------------------------- */
                if (ds.GetGCPCount() > 0) {
                    strInfo += "\nGCP Projection: " + ds.GetGCPProjection();
                    GCP[] GCPs = ds.GetGCPs();
                    for (int i = 0; i < ds.GetGCPCount(); i++) {
                        strInfo += "\nGCP[" + i + "]: Id=" + GCPs[i].Id + ", Info=" + GCPs[i].Info;
                        strInfo += "\n          (" + GCPs[i].GCPPixel + "," + GCPs[i].GCPLine + ") -> ("
                                    + GCPs[i].GCPX + "," + GCPs[i].GCPY + "," + GCPs[i].GCPZ + ")";
                        strInfo += "\n";
                    }
                    strInfo += "\n";

                    double[] transform = new double[6];
                    Gdal.GCPsToGeoTransform(GCPs, transform, 0);
                    strInfo += "\nGCP Equivalent geotransformation parameters: " + ds.GetGCPProjection();
                    for (int i = 0; i < 6; i++)
                        strInfo += "\nt[" + i + "] = " + transform[i].ToString();
                    strInfo += "\n";
                }

                /* -------------------------------------------------------------------- */
                /*      Get raster band                                                 */
                /* -------------------------------------------------------------------- */
                for (int iBand = 1; iBand <= ds.RasterCount; iBand++) {
                    Band band = ds.GetRasterBand(iBand);
                    strInfo += "\nBand " + iBand + " :";
                    strInfo += "\n   DataType: " + Gdal.GetDataTypeName(band.DataType);
                    strInfo += "\n   ColorInterpretation: " + Gdal.GetColorInterpretationName(band.GetRasterColorInterpretation());
                    ColorTable ct = band.GetRasterColorTable();
                    if (ct != null)
                        strInfo += "\n   Band has a color table with " + ct.GetCount() + " entries.";

                    strInfo += "\n   Description: " + band.GetDescription();
                    strInfo += "\n   Size (" + band.XSize + "," + band.YSize + ")";
                    int BlockXSize, BlockYSize;
                    band.GetBlockSize(out BlockXSize, out BlockYSize);
                    strInfo += "\n   BlockSize (" + BlockXSize + "," + BlockYSize + ")";
                    double val;
                    int hasval;
                    band.GetMinimum(out val, out hasval);
                    if (hasval != 0) strInfo += "\n   Minimum: " + val.ToString();
                    band.GetMaximum(out val, out hasval);
                    if (hasval != 0) strInfo += "\n   Maximum: " + val.ToString();
                    band.GetNoDataValue(out val, out hasval);
                    if (hasval != 0) strInfo += "\n   NoDataValue: " + val.ToString();
                    band.GetOffset(out val, out hasval);
                    if (hasval != 0) strInfo += "\n   Offset: " + val.ToString();
                    band.GetScale(out val, out hasval);
                    if (hasval != 0) strInfo += "\n   Scale: " + val.ToString();

                    for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++) {
                        Band over = band.GetOverview(iOver);
                        strInfo += "\n      OverView " + iOver + " :";
                        strInfo += "\n         DataType: " + over.DataType;
                        strInfo += "\n         Size (" + over.XSize + "," + over.YSize + ")";
                        strInfo += "\n         PaletteInterp: " + over.GetRasterColorInterpretation().ToString();
                    }
                }
            }
            catch (Exception e) {
                strInfo += "\nApplication error: " + e.Message;
            }

            return strInfo;
        }

        private static string GDALInfoGetPosition(Dataset ds, double x, double y) {
            double[] adfGeoTransform = new double[6];
            double dfGeoX, dfGeoY;
            ds.GetGeoTransform(adfGeoTransform);

            dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y;
            dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y;

            return dfGeoX.ToString() + ", " + dfGeoY.ToString();
        }
    }
}